package org.stvd.common.security.support;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.access.method.AbstractMethodSecurityMetadataSource;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.stvd.common.Consts;
import org.stvd.entities.admin.Resources;
import org.stvd.entities.admin.Roles;
import org.stvd.service.admin.ResourcesService;
import org.stvd.service.admin.RolesService;

public class MethodSecurityMetadataSource extends AbstractMethodSecurityMetadataSource {
    private final PathMatcher pathMatcher = new AntPathMatcher();

    private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

    private ResourcesService resourcesService;
    
    private RolesService rolesService;

    public ResourcesService getResourcesService() {
        return resourcesService;
    }

    public void setResourcesService(ResourcesService resourcesService) {
        this.resourcesService = resourcesService;
    }

    public RolesService getRolesService() {
        return rolesService;
    }

    public void setRolesService(RolesService rolesService) {
        this.rolesService = rolesService;
    }

    public MethodSecurityMetadataSource(ResourcesService resourcesService) {
        this.resourcesService = resourcesService;
        loadResourceDefine();
    }

    public static void setResourceMap(Map<String, Collection<ConfigAttribute>> resourcemap) {
        if (resourceMap == null) {
            resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
        } else {
            resourceMap.clear();
        }
        resourceMap.putAll(resourcemap);
    }

    /**
     * 从数据库中,调取所有的方法和权限的影射配置并做缓存
     */
    private void loadResourceDefine() {
        if (resourceMap == null) {
            resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
        } else {
            resourceMap.clear();
        }
        List<Resources> resources = this.resourcesService.findResourcesByType("METHOD", Consts.GUID);
        for (Resources resource : resources) {
            Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
            // 以权限名封装为Spring的security Object,例如ROLE_USER,ROLE_ADMIN
            List<Roles> roleList = rolesService.getRolesByResId(resource.getResId());
            for (Roles role : roleList) {
                ConfigAttribute configAttribute = new SecurityConfig(role.getRoleCode());
                configAttributes.add(configAttribute);
            }
            resourceMap.put(resource.getContent(), configAttributes);
        }
    }

    public Collection<ConfigAttribute> getAttributes(Method method, Class<?> arg1) {
        Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
        String methodName = (method.getDeclaringClass().getName() + "." + method.getName());

        System.out.println("请求方法:" + methodName);

        if (resourceMap != null && !resourceMap.isEmpty()) {
            Iterator<String> iterator = resourceMap.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                if (pathMatcher.match(key, methodName)) {
                    configAttributes.addAll(resourceMap.get(key));
                }
            }
            if (configAttributes.isEmpty()) {
                configAttributes.add(new SecurityConfig("nobody"));
            }
            for (ConfigAttribute configAttribute : configAttributes) {
                System.out.println("请求url匹配角色：" + configAttribute.toString());
            }
            return configAttributes;
        }
        return null;

        //
        // String matchurl=""; //临时变量 这里的匹配原则,总是找最短的匹配.
        // Collection<ConfigAttribute> ret=null;
        // if (resourceMap == null || resourceMap.size() == 0)
        // return null;
        // Iterator<String> iterator = resourceMap.keySet().iterator();
        // logger.debug("map.count="+resourceMap.size());
        // String key = null;
        // logger.debug("iterator ="+iterator.hasNext());
        // while (iterator.hasNext())
        // {
        // key = (String) iterator.next();
        // logger.debug("key = "+key +" methodName ="+methodName);
        // boolean matched = pathMatcher.match(key, methodName);
        //
        // System.out.println("方法匹配Method： '" + methodName + "；模式为 " + key +
        // "；是否被匹配：" + matched);
        //
        // if (matched && key.length()>=matchurl.length())
        // {
        // matchurl=key;
        // }
        // }
        // if(resourceMap.containsKey(matchurl))
        // {
        // ret=(Collection<ConfigAttribute>) resourceMap.get(matchurl);
        // }
        // return ret;
    }

    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

}